package tcpserver

import (
	"bytes"
	"encoding/binary"
	"github.com/astaxie/beego/logs"
	"sync"
	"time"
)

//上报频率默认值
//const reportTheFrequency = 1000000000

var (
	upConns = sync.Map{}
)

func NewUpLinkServer(addr string) {
	server := New(addr)
	server.OnNewClient(func(c *Client) {
		//将新连接加入到tcp连接池
		logs.Debug("有新的连接加入：", c.conn.RemoteAddr().String())
		// 开启 TCP Keep-Alive 机制
		//if err := c.SetKeepAlive(10 * time.Second); err != nil {
		//	logs.Error(err.Error())
		//	return
		//}
		upConns.Store(c.conn.RemoteAddr().String(), c)
	})
	server.OnNewMessage(func(c *Client, message []byte) {

		logs.Debug("有新的消息：%s 来自：%s", string(message), c.conn.RemoteAddr().String())
		//if string(message) == "ping" {
		//	if err := c.Send(Packet([]byte("pong"))); err != nil {
		//		logs.Error(err.Error())
		//	}
		//}
	})
	server.OnClientConnectionClosed(func(c *Client, err error) {
		upConns.Delete(c.conn.RemoteAddr().String())
		logs.Error("客户端（%s）连接关闭（%s）", c.conn.RemoteAddr(), err)
	})
	go server.Listen()
}

func SendMessageToAll(data []byte) {
	upConns.Range(func(addr, client interface{}) bool {
		c := client.(*Client)
		if err := c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second)); err != nil {
			logs.Error(err.Error())
		}
		if err := c.Send(Packet(data)); err != nil {
			return false
		}
		logs.Info("向客户端（%s）发送了消息（%s）", c.conn.RemoteAddr(), string(data))
		return true
	})
}

const (
	constHeader         = ""
	constHeaderLength   = 0
	constSaveDataLength = 4
)

// Packet 封包
func Packet(message []byte) []byte {
	return append(append([]byte(constHeader), intToBytes(len(message))...), message...)
}

// Unpack 解包
func Unpack(buffer []byte) (full [][]byte, cut []byte) {
	length := len(buffer)
	var i int
	for i = 0; i < length; i++ {
		if length < i+constHeaderLength+constSaveDataLength {
			break
		}
		if string(buffer[i:i+constHeaderLength]) == constHeader {
			messageLength := bytesToInt(buffer[i+constHeaderLength : i+constHeaderLength+constSaveDataLength])
			if length < i+constHeaderLength+constSaveDataLength+messageLength {
				break
			}
			data := buffer[i+constHeaderLength+constSaveDataLength : i+constHeaderLength+constSaveDataLength+messageLength]
			//readerChannel <- data
			full = append(full, data)
			i += constHeaderLength + constSaveDataLength + messageLength - 1
		}
	}
	if i == length {
		return full, nil
	}
	return nil, buffer[i:]
}

//整形转换成字节
func intToBytes(n int) []byte {
	x := int32(n)

	bytesBuffer := bytes.NewBuffer([]byte{})
	_ = binary.Write(bytesBuffer, binary.BigEndian, x)
	return bytesBuffer.Bytes()
}

//字节转换成整形
func bytesToInt(b []byte) int {
	bytesBuffer := bytes.NewBuffer(b)

	var x int32
	_ = binary.Read(bytesBuffer, binary.BigEndian, &x)
	return int(x)
}
